﻿using Microsoft.Win32;
using psafth.RCTiming.Common;
using psafth.RCTiming.Common.Utilities;
using Excel = Microsoft.Office.Interop.Excel;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace psafth.RCTiming.Main.Pages.Dialogs
{
    /// <summary>
    /// Interaction logic for CreateEventDialog.xaml
    /// </summary>
    public partial class CreateEventDialog : Window
    {
        private Event _newEvent;
        private int _currentStep;
        private MainWindow _mainWindow;

        public DBContext DbContext
        {
            get
            {
                return this._mainWindow.DbContext;
            }
            set
            {
                this._mainWindow.DbContext = value;
            }
        }

        public CreateEventDialog(MainWindow m)
        {
            _mainWindow = m;
            InitializeComponent();

            _currentStep = 0;

            _newEvent = new Event();
            _newEvent.Participants = new ObservableCollectionExt<EventParticipant>();

            FetchAndBindClubs();
            FetchAndBindDrivers();
            FetchAndBindRaceClasses();

            BindParticipants();

            ShowStep();
        }

        private void ShowStep()
        {
            switch (_currentStep)
            {
                case 0:
                    gStepOne.Visibility = System.Windows.Visibility.Visible;
                    gStepTwo.Visibility = System.Windows.Visibility.Collapsed;
                    btnPrevious.IsEnabled = false;
                    break;
                case 1:
                    gStepOne.Visibility = System.Windows.Visibility.Collapsed;
                    gStepTwo.Visibility = System.Windows.Visibility.Visible;
                    btnPrevious.IsEnabled = true;
                    break;
                case 2:
                    gStepOne.Visibility = System.Windows.Visibility.Collapsed;
                    gStepTwo.Visibility = System.Windows.Visibility.Collapsed;
                    btnPrevious.IsEnabled = true;
                    break;
            }

            if (_currentStep == 2)
            {
                btnNext.Content = "Slutför";
            }
            else
            {
                btnNext.Content = "Nästa";
            }
        }

        private void BindParticipants()
        {
            UpdateClassesWithParticipants();

            CompetitorGrid.ItemsSource = _newEvent.Participants;
        }

        private void UpdateClassesWithParticipants()
        {
            for (int i = tcCompetitors.Items.Count - 1; i > 0; i--)
                tcCompetitors.Items.RemoveAt(i);

            List<RaceClass> raceClassesWithParticipants = _newEvent.Participants.Select(r => r.RaceClass).DistinctBy(p => p.Id).ToList();

            foreach (RaceClass raceClass in raceClassesWithParticipants)
            {
                DataGrid dg = new DataGrid()
                {
                    ItemsSource = _newEvent.Participants.Where(p => p.RaceClassId.Equals(raceClass.Id)),
                    AutoGenerateColumns = false
                };

                dg.Columns.Add(new DataGridTextColumn()
                {
                    Header = "L.Nr",
                    Binding = new Binding("Driver.LicenceNumber"),
                    Width = DataGridLength.Auto
                });

                dg.Columns.Add(new DataGridTextColumn()
                {
                    Header = "Namn",
                    Binding = new Binding("Driver.FullName"),
                    Width = new DataGridLength(1, DataGridLengthUnitType.Star)
                });

                dg.Columns.Add(new DataGridTextColumn()
                {
                    Header = "Transponder",
                    Binding = new Binding("TransponderId"),
                    Width = new DataGridLength(1, DataGridLengthUnitType.Star)
                });

                ContextMenu t = new System.Windows.Controls.ContextMenu();

                t.Items.Add("test1");
                t.Items.Add("test2");


                TabItem ti = new TabItem()
                {
                    Header = raceClass.Name,
                    Content = dg
                };

                tcCompetitors.Items.Add(ti);
            }
        }

        private void FetchAndBindDrivers()
        {
            cbDrivers.ItemsSource = DbContext.Drivers.OrderBy(r => r.FirstName).ToList();
        }

        private void FetchAndBindRaceClasses()
        {
            cbClass.ItemsSource = DbContext.RaceClasses.AsEnumerable().OrderBy(r => r.Name, new NaturalSortComparer<string>()).ToList();
        }

        private void FetchAndBindClubs()
        {
            foreach (Club club in DbContext.Clubs.OrderBy(c => c.FullName))
            {
                cbClubs.Items.Add(club.FullName);
            }
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void btnAddCompetitor_Click(object sender, RoutedEventArgs e)
        {
            EventParticipant ep = new EventParticipant();

            try
            {
                if (cbDrivers.SelectedItem != null)
                {
                    if (cbDrivers.SelectedItem is Driver)
                    {
                        Driver selectedDriver = (Driver)cbDrivers.SelectedItem;

                        if (selectedDriver != null)
                        {
                            ep.DriverId = selectedDriver.Id;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // Error while getting the selected driver
            }

            try
            {
                if (cbClass.SelectedItem != null)
                {
                    if (cbClass.SelectedItem is RaceClass)
                    {
                        RaceClass selectedClass = (RaceClass)cbClass.SelectedItem;

                        if (selectedClass != null)
                        {
                            ep.RaceClassId = selectedClass.Id;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // Error while getting the selected class
            }


            try
            {
                if (cbTransponder.SelectedItem != null)
                {
                    if (cbTransponder.SelectedItem is Transponder)
                    {
                        Transponder selectedTransponder = (Transponder)cbTransponder.SelectedItem;

                        if (selectedTransponder != null)
                        {
                            ep.TransponderId = selectedTransponder.TransponderId;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // Error while getting the selected class
            }


            if (ep.Driver != null && ep.RaceClass != null)
            {

                if (_newEvent.Participants.Where(d => d.DriverId == ep.DriverId && d.RaceClassId == ep.RaceClassId).Count() < 1)
                    _newEvent.Participants.Add(ep);
                else
                    MessageBox.Show(string.Format("Föraren {0} är redan tillagd i klassen {1}", ep.Driver.FullNameWithLicence, ep.RaceClass.Name), "Stopp", MessageBoxButton.OK, MessageBoxImage.Stop);
            }

            BindParticipants();
        }

        private void cbDrivers_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                if (cbDrivers.SelectedItem != null)
                {
                    if (cbDrivers.SelectedItem is Driver)
                    {
                        Driver selectedDriver = (Driver)cbDrivers.SelectedItem;

                        if (selectedDriver != null)
                        {
                            cbTransponder.ItemsSource = DbContext.Transponders.Where(t => t.Driver.Id == selectedDriver.Id).ToList();
                            btnAddCompetitor.IsEnabled = true;
                        }
                        else
                        {
                            MessageBox.Show("Föraren hittades inte", "Fel", MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                    else
                    {
                        MessageBox.Show("Föraren hittades inte", "Fel", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                }
                else
                {
                    btnAddCompetitor.IsEnabled = false;
                }
            }
            catch (Exception ex)
            {

            }
        }

        private void btnNext_Click(object sender, RoutedEventArgs e)
        {
            _newEvent.EventName = tbTitle.Text;
            _newEvent.StartDate = dpStartDate.SelectedDate ?? DateTime.Now.Date;
            _newEvent.EndDate = dpEndDate.SelectedDate ?? DateTime.Now.Date;
            _newEvent.Organizer = cbClubs.Text;



            if (_currentStep < 2 && _currentStep >= 0)
            {
                _currentStep++;
                ShowStep();
            }
            else
            {
                DbContext.Events.Add(_newEvent);
                DbContext.SaveChanges();
                this.Close();
            }
        }

        private void btnPrevious_Click(object sender, RoutedEventArgs e)
        {
            _currentStep--;
            ShowStep();
        }

        private void btnUploadExcel_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            if (openFileDialog.ShowDialog() == true)
            {
                Excel.Application xlApp = new Excel.Application();

                Excel.Workbook workBook = xlApp.Workbooks.Open(openFileDialog.FileName);

                int numberOfSheets = workBook.Sheets.Count;

                DatabaseHelper.DoWithDB<DBContext>(db =>
                {
                    foreach (Excel.Worksheet sheet in workBook.Sheets)
                    {
                        string rcName = sheet.Name;

                        RaceClass rc = db.RaceClasses.FirstOrDefault(r => r.Name == rcName);

                        if (rc == null)
                            throw new Exception(string.Format("RaceClass {0} could not be found", rcName));

                        Excel.Range range = sheet.UsedRange;

                        for (int i = 2; i <= range.Rows.Count; i++)
                        {
                            string licenceNumber = range.Cells[i, 1].Text;
                            string fullName = range.Cells[i, 2].Text;
                            string primaryTransponderValue = range.Cells[i, 3].Text;
                            string secondaryTransponderValue = range.Cells[i, 4].Text;
                            string frequency = range.Cells[i, 5].Text;
                            string email = range.Cells[i, 6].Text;
                            string telephone = range.Cells[i, 7].Text;
                            string group = range.Cells[i, 8].Text;

                            int primaryTransponderId = 0;
                            int secondaryTransponderId = 0;

                            Transponder primaryTransponder = null;
                            Transponder secondaryTransponder = null;

                            if (!string.IsNullOrWhiteSpace(primaryTransponderValue))
                            {
                                if (int.TryParse(primaryTransponderValue, out primaryTransponderId))
                                    primaryTransponder = new Transponder()
                                    {
                                        TransponderId = primaryTransponderId
                                    };
                            }

                            if (!string.IsNullOrWhiteSpace(secondaryTransponderValue))
                            {
                                if (int.TryParse(primaryTransponderValue, out secondaryTransponderId))
                                    secondaryTransponder = new Transponder()
                                    {
                                        TransponderId = secondaryTransponderId
                                    };
                            }

                            Driver driver = db.Drivers.FirstOrDefault(d => d.LicenceNumber == licenceNumber);

                            if (driver == null)
                            {
                                string[] nameChunks = fullName.Split(' ');

                                string firstName = nameChunks.First();
                                string lastName = string.Empty;

                                if (nameChunks.Count() > 1)
                                    lastName = String.Join(" ", nameChunks.Skip(1));

                                driver = new Driver()
                                {
                                    LicenceNumber = licenceNumber,
                                    FirstName = firstName,
                                    LastName = lastName,
                                    EmailAddress = email
                                };

                                if (primaryTransponder != null)
                                    driver.Transponders.Add(primaryTransponder);

                                if (secondaryTransponder != null)
                                    driver.Transponders.Add(secondaryTransponder);

                                db.Drivers.Add(driver);

                                db.SaveChanges();
                            }

                            if (primaryTransponder != null)
                                if (!driver.Transponders.Exists(t => t.TransponderId == primaryTransponder.TransponderId))
                                    driver.Transponders.Add(primaryTransponder);

                            if (secondaryTransponder != null)
                                if (!driver.Transponders.Exists(t => t.TransponderId == secondaryTransponder.TransponderId))
                                    driver.Transponders.Add(secondaryTransponder);

                            _newEvent.Participants.Add(new EventParticipant()
                            {
                                DriverId = driver.Id,
                                RaceClassId = rc.Id,
                                TransponderId = primaryTransponderId
                            });

                            db.SaveChanges();
                        }
                    }
                });

                BindParticipants();

                //Excel._Worksheet eventWorksheet = workBook.Sheets[1];

                //Excel.Range eventRange = eventWorksheet.UsedRange;

                //string eventFullname = eventRange.Cells[2, 2].Text;
                //string eventShortname = eventRange.Cells[3, 2].Text;
                //string eventOrganizer = eventRange.Cells[4, 2].Text;
                //string eventLocation = eventRange.Cells[5, 2].Text;
                //string eventDateString = eventRange.Cells[6, 2].Text;

                //DateTime eventDate = new DateTime();

                //DateTime.TryParse(eventDateString, out eventDate);

                //// For each heatsheet. Create heat(s).
                //for (int i = 2; i <= workBook.Sheets.Count; i++)
                //{
                //    if (workBook.Sheets[i].Visible < 0)
                //    {
                //        Excel.Worksheet currentWorksheet = workBook.Sheets[i];

                workBook.Close();
            }
        }
    }
}
